home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Format / p2flatten / flatten_chan.c next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  7.6 KB  |  317 lines

  1. /* flatten_chan: channel to flatten body parts into a P2 message */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Format/p2flatten/RCS/flatten_chan.c,v 6.0 1991/12/18 20:20:12 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Format/p2flatten/RCS/flatten_chan.c,v 6.0 1991/12/18 20:20:12 jpo Rel $
  9.  *
  10.  * $Log: flatten_chan.c,v $
  11.  * Revision 6.0  1991/12/18  20:20:12  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "util.h"
  19. #include "qmgr.h"
  20. #include "q.h"
  21. #include "prm.h"
  22. #include "dr.h"
  23. #include "retcode.h"
  24. #include <sys/stat.h>
  25. #include "sys.file.h"
  26.  
  27. extern char    *quedfldir;
  28. extern CHAN    *ch_nm2struct();
  29. extern char    *cont_p2;
  30. extern void    rd_end(), sys_init(), err_abrt();
  31. static CHAN    *mychan;
  32. static char    *this_msg, *this_chan;
  33.  
  34. static struct type_Qmgr_DeliveryStatus    *process();
  35. static int                initialise();
  36. static int                security_check();
  37. static void                dirinit();
  38. static ADDR                *getnthrecip ();
  39. static int                processMsg();
  40. static int                doComb();
  41. static int                x40084;
  42. /*   */
  43. /* main routine */
  44.  
  45. main(argc, argv)
  46. int     argc;
  47. char    **argv;
  48. {
  49.     sys_init(argv[0]);
  50.     dirinit ();
  51. #ifdef PP_DEBUG
  52.     if (argc>1 && (strcmp(argv[1],"debug") == 0))
  53.         debug_channel_control (argc, argv, initialise, process, NULLIFP);
  54.     else
  55. #endif
  56.     channel_control(argc, argv, initialise, process, NULLIFP);
  57. }
  58.  
  59. /*   */
  60. /* move to correct place in file system */
  61.  
  62. static void dirinit ()
  63. {
  64.     if (chdir (quedfldir) < 0)
  65.         err_abrt( RP_LIO, " Unable to change directory to '%s'",
  66.             quedfldir);
  67. }
  68.  
  69. /*   */
  70. /* channel initialise routine */
  71.  
  72. static int initialise (arg)
  73. struct type_Qmgr_Channel    *arg;
  74. {
  75.     char    *name;
  76.  
  77.     name = qb2str(arg);
  78.  
  79.     if ((mychan = ch_nm2struct(name)) == NULLCHAN) {
  80.         PP_OPER(NULLCP, 
  81.             ("Chans/p2flatten : Channel '%s' not known",name));
  82.         if (name != NULL) free(name);
  83.         return NOTOK;
  84.     }
  85.  
  86.     return OK;
  87. }
  88.  
  89. /*   */
  90.  
  91. static int security_check (msg)
  92. struct type_Qmgr_ProcMsg    *msg;
  93. {
  94.     char    *msg_file = NULL,
  95.         *msg_chan = NULL;
  96.     int    result;
  97.  
  98.     result = TRUE;
  99.     msg_file = qb2str(msg->qid);
  100.     msg_chan = qb2str(msg->channel);
  101.  
  102.     if ((mychan == NULLCHAN) || (strcmp(msg_chan, mychan->ch_name) != 0)) {
  103.         PP_LOG(LLOG_EXCEPTIONS,
  104.             ("Chans/flatten_chan channel err: '%s'",msg_chan));
  105.         result = FALSE;
  106.     }
  107.  
  108.     if (msg_file != NULL) free(msg_file);
  109.     if (msg_chan != NULL) free(msg_chan);
  110.     return result;
  111. }
  112.  
  113. /*   */
  114. /* routine to do split */
  115.  
  116. extern int err_fatal;
  117. int    first_failureDR;
  118.  
  119. static struct type_Qmgr_DeliveryStatus *process (arg)
  120. struct type_Qmgr_ProcMsg    *arg;
  121. {
  122.     struct prm_vars            prm;
  123.     Q_struct            que;
  124.     ADDR                *sender = NULL;
  125.     ADDR                *recips = NULL;
  126.     int                rcount, retval;
  127.     struct type_Qmgr_UserList    *ix;
  128.     ADDR                *adr;
  129.     char                *error;
  130.  
  131.     bzero((char *) &que,sizeof(que));
  132.     bzero((char *) &prm,sizeof(prm));
  133.     first_failureDR = TRUE;
  134.     delivery_init(arg->users);
  135.     delivery_setall(int_Qmgr_status_messageFailure);
  136.         
  137.     if (security_check(arg) != TRUE)
  138.         return deliverystate;
  139.  
  140.     if (this_msg != NULL) free(this_msg);
  141.     if (this_chan != NULL) free(this_chan);
  142.  
  143.     this_msg = qb2str(arg->qid);
  144.     this_chan = qb2str(arg->channel);
  145.  
  146.     PP_LOG(LLOG_TRACE,
  147.         ("P2 flatten on msg '%s' through '%s'",this_msg,this_chan));
  148.         
  149.     if (rp_isbad(rd_msg(this_msg,&prm,&que,&sender,&recips,&rcount))) {
  150.         PP_LOG(LLOG_EXCEPTIONS,
  151.             ("Chans/flatten_chan rd_msg err: '%s'",this_msg));
  152.         rd_end();
  153.         return delivery_setallstate (int_Qmgr_status_messageFailure,
  154.                          "Can't read message");
  155.     }
  156.  
  157.     for (ix = arg->users; ix; ix=ix->next) {
  158.         error = NULLCP;
  159.         if ((adr = getnthrecip(&que, ix->RecipientId->parm)) == NULL) {
  160.             PP_LOG(LLOG_EXCEPTIONS,
  161.                 ("Chans/flatten_chan : failed to find recipient %d",ix->RecipientId->parm));
  162.             delivery_setstate(ix->RecipientId->parm,
  163.                       int_Qmgr_status_messageFailure,
  164.                       "Unable to find specified recipient");
  165.             continue;
  166.         }
  167.  
  168.         switch (chan_acheck (adr, mychan, 1, (char **) NULL)) {
  169.             case OK:
  170.             if (processMsg(this_msg,adr,&error) == NOTOK) {
  171.                 PP_LOG(LLOG_EXCEPTIONS,
  172.                     ("Chans/flatten_chan : failed to process message '%s' for recipient %d",this_msg,adr->ad_no));
  173.                 if (err_fatal == TRUE) {
  174.                     set_1dr(&que, adr->ad_no, this_msg,
  175.                         DRR_CONVERSION_NOT_PERFORMED,
  176.                         DRD_CONTENT_SYNTAX_ERROR,
  177.                         (error == NULLCP) ? "Unable to flatten the p2" : error);
  178.                     delivery_set(adr->ad_no,
  179.                              (first_failureDR == TRUE) ? int_Qmgr_status_negativeDR : int_Qmgr_status_failureSharedDR);
  180.                     first_failureDR = FALSE;
  181.                 } else
  182.                     delivery_setstate(adr->ad_no,
  183.                               int_Qmgr_status_messageFailure,
  184.                               (error == NULLCP) ? "Failed to flatten message" : error);
  185.             } else {
  186.                 adr->ad_rcnt++;
  187.                 wr_ad_rcntno(adr, adr->ad_rcnt);
  188.                 delivery_set(adr->ad_no,
  189.                          int_Qmgr_status_success);
  190.             }
  191.             break;
  192.             default:
  193.             break;
  194.         }
  195.         if (error != NULLCP)
  196.             free(error);
  197.     }
  198.     if (rp_isbad(retval = wr_q2dr(&que, this_msg))) {
  199.                 PP_LOG(LLOG_EXCEPTIONS,
  200.                        ("%s wr_q2dr failure '%d'",mychan->ch_name,retval));
  201.                 delivery_resetDRs(int_Qmgr_status_messageFailure);
  202.         }
  203.     rd_end();
  204.     q_free (&que);
  205.     prm_free(&prm);
  206.     return deliverystate;
  207. }
  208.  
  209. /*   */
  210. /* returns ok if processed msg on mychan for recip */
  211. static int processMsg (msg,recip, perr)
  212. char    *msg;
  213. ADDR    *recip;
  214. char    **perr;
  215. {
  216.     char        *origdir = NULL,
  217.             *newdir = NULL;
  218.     int        result = OK;
  219.     struct stat    statbuf;
  220.     
  221.     if (qid2dir(msg, recip, TRUE, &origdir) != OK) {
  222.         PP_LOG(LLOG_EXCEPTIONS,
  223.             ("Chans/flatten_chan original directory not found for recipient %d of message '%s'",recip->ad_no, msg));
  224.         *perr = strdup("Can't find source directory");
  225.         result = NOTOK;
  226.     }
  227.  
  228.     /* temporary change to get new directory name */
  229.     recip->ad_rcnt++;
  230.     if ((result == OK)
  231.         && (qid2dir(msg, recip, FALSE, &newdir) != OK)) {
  232.         PP_LOG(LLOG_EXCEPTIONS,
  233.             ("Chans/flatten_chan couldn't construct new directory name for recipient %d of message '%s'", recip->ad_no, msg));
  234.         *perr = strdup("Can't construct destination directory");
  235.         result = NOTOK;
  236.     }
  237.     recip->ad_rcnt--;
  238.  
  239.     if ((result == OK)
  240.         && (stat(newdir, &statbuf) == OK)
  241.         && ((statbuf.st_mode & S_IFMT) == S_IFDIR)) {
  242.             /* new directory already exists, os processing already done */
  243.             if (origdir != NULL) free(origdir);
  244.             if (newdir != NULL) free(newdir);
  245.             return OK;
  246.     }
  247.     x40084 = (lexequ(recip->ad_content, cont_p2) == 0) ? TRUE : FALSE;
  248.     if ((result == OK) && (doComb(origdir,newdir,msg, perr) != OK))
  249.         result = NOTOK;
  250.  
  251.     if (origdir != NULL) free(origdir);
  252.     if (newdir != NULL) free(newdir);
  253.     return result;
  254. }
  255.  
  256. /*   */
  257. /* combs files in orig into p2 in new */
  258. static int doComb (old, new,msg,perr)
  259. char    *old,
  260.     *new,
  261.     *msg,
  262.     **perr;
  263. {
  264.     struct stat    statbuf;
  265.     char        tmpdir[MAXPATHLENGTH], buf[BUFSIZ];
  266.     int        result = OK;
  267.     
  268.     (void) sprintf(tmpdir, "%s/tmp.%s",
  269.                msg,mychan->ch_name);
  270.  
  271.     if (stat(tmpdir, &statbuf) == OK) {
  272.         /* exists so remove it */
  273.         char *cmdline = malloc((unsigned) (strlen("rm -rf ") + strlen(tmpdir)+1));
  274.         (void) sprintf(cmdline, "rm -rf %s",tmpdir);
  275.         system(cmdline);
  276.         if (cmdline != NULL) free(cmdline);
  277.     }
  278.  
  279.     if (mkdir(tmpdir, 0777) != OK) {
  280.         PP_SLOG(LLOG_EXCEPTIONS, tmpdir,
  281.             ("Can't make directory"));
  282.         (void) sprintf (buf,
  283.                 "Unable to make temp directory '%s'",
  284.                 tmpdir);
  285.         *perr = strdup(buf);
  286.         result = NOTOK;
  287.     }
  288.     if (result == OK) 
  289.         result = flatten(old,tmpdir, x40084, perr);
  290.     if ((result == OK) && (rename(tmpdir,new) == -1)) {
  291.         PP_SLOG(LLOG_EXCEPTIONS, "rename",
  292.             ("Unable to rename directory '%s' to '%s'",
  293.             tmpdir, new));
  294.         (void) sprintf (buf,
  295.                 "Unable to rename directory '%s' to '%s'",
  296.                 tmpdir, new);
  297.         *perr = strdup(buf);
  298.         result = NOTOK;
  299.     }
  300.  
  301.     return result;
  302. }
  303.  
  304. static ADDR *getnthrecip(que, num)
  305. Q_struct    *que;
  306. int        num;
  307. {
  308.     ADDR *ix = que->Raddress;
  309.  
  310.     if (num == 0)
  311.         return que->Oaddress;
  312.     while ((ix != NULL) && (ix->ad_no != num))
  313.         ix = ix->ad_next;
  314.     return ix;
  315. }
  316.  
  317.